package com.zyk.utils;

import net.bytebuddy.agent.ByteBuddyAgent;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ProcessUtils {

    public synchronized static String currentId() {
        return ByteBuddyAgent.ProcessProvider.ForCurrentVm.INSTANCE.resolve();
    }

    public static int start(ProcessBuilder pb, OutputStream out) throws Exception {
        return start(pb, out, null);
    }

    public static int start(ProcessBuilder pb, OutputStream out, OutputStream err) throws Exception {
        Process p = pb.start();
        Thread[] threads = {
                out != null ? new Thread(new RedirectOutput(p.getInputStream(), out)) : null,
                err != null ? new Thread(new RedirectOutput(p.getErrorStream(), err)) : null
        };
        for (Thread thread : threads) {
            if (thread != null) {
                thread.start();
            }
        }
        for (Thread thread : threads) {
            if (thread != null) {
                thread.join();
            }
        }
        return p.waitFor();
    }

    static class RedirectOutput implements Runnable {
        private static final int BUFF_SIZE = 1024;
        private final InputStream origin;
        private final OutputStream dest;

        RedirectOutput(InputStream origin, OutputStream dest) {
            this.origin = origin;
            this.dest = dest;
        }

        public void run() {
            int length;
            byte[] buffer = new byte[BUFF_SIZE];

            try {
                while ((length = origin.read(buffer)) != -1) {
                    dest.write(buffer, 0, length);
                }
            } catch (IOException e) {
                throw new RuntimeException("ERROR: Redirect output failed.", e);
            }
        }
    }
}
